package com.cskaoyan.javase.oop1._13block._2building;

/**
 * 构造代码块
 * 语法：
 * 声明在类的成员位置，使用{}声明的代码块就是构造代码块
 * 作用：随着构造器的执行而执行，用来在创建对象过程中，给成员变量赋值。
 * 这里，总结一下在创建对象过程当中，给成员变量赋值的方式：
 *      1.默认初始化，具有默认值
 *      2.显式赋值
 *      3.构造器赋值
 *      4.构造代码块赋值
 * “掐头去尾”原则：默认初始化是第一步，构造器赋值是最后一步
 * 接下来验证显式赋值和构造代码块赋值谁先谁后：
 * 通过测试，很明显显式赋值和构造代码块赋值是按照代码的书写顺序，从上往下执行
 *
 * 把构造代码块赋值写在显式赋值的上面，多少有点奇怪，那么为什么可以这么写呢？
 * 构造代码块为什么会随着构造器的执行而执行呢？
 * 通过查看反编译代码，发现编译后的代码是不存在构造代码块结构的，而是：
 * “智能”的把构造代码块中的代码或者显式赋值的代码，加入到所有构造器的前几行
 * 智能的目的是：为了保证构造代码块赋值和显式赋值按照代码的书写顺序从上到下执行
 *
 * 构造代码块会将其中的代码加入类的每一个构造器中，这样，我们可以提取公因式，假如有一段代码块在每个构造器中都需要执行
 * 这样就可以放入构造代码块中
 *
 *
 *
 * @since 09:58
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // Animal a = new Animal();
        // System.out.println(a.age);

        System.out.println("-------------------------");
        System.out.println(Animal.name);
    }
}

class Animal {
    // 构造代码块
    {
        age = 19;
        /*
            构造代码块中，可以不可以给静态成员变量赋值？
            是可以的
            为什么？
            静态成员变量类加载时期完成初始化，而构造代码块在创建对象中执行
            类加载在前，创建对象在后
            所以肯定是可以访问的
            这样，意味着静态成员变量的赋值依赖于创建对象的过程
            在正常情况下，这样不好（除非有特殊用途）
            我们需要一种在类加载过程中，给静态成员变量赋值的代码块——就是静态代码块
         */
        name = "张三";
    }

    int age = 18;
    static String name;

    public Animal() {
    }

    public Animal(int age) {
        this.age = age;
    }
}
